import jquery from 'jquery'

const _adjacent_where = ['afterend', 'afterbegin', 'beforebegin', 'beforeend']
const _adjacent_query = ['after', 'prepend', 'before', 'append']
// 创建一个div /@ s -> html
const _div = function(s) {
	let o = document.createElement('div')
	if (s) o.innerHTML = s
	try {return o} catch(e) {return false}
	finally {o = null}
}
const frag = function(s) {
	let d = typeof s === 'string' ? _div(s) : s
  let f = document.createDocumentFragment()
	while (d.firstChild)
		f.appendChild(d.firstChild);
	try {return f} catch(e) {return false}
	finally {d = f = null}
}

const el = function(o) {
  if (o) {
    return o.isWidget ? o.el() : o
  }
}
// o -> el, s -> html string/object, r -> where[`after`, `prepend`, `before`, `append`]
const html = function(o, s, r) {
	if (r == null) {
		if (s == null) return o.innerHTML
		try {o.innerHTML = s} catch(ex) {
			while (o.firstChild)
				o.removeChild(o.firstChild)
			html(o, s, 3)
		}
	} else {
		let b
		if (typeof s === 'string') {
			try {
				o.nodeType === 3 ? jquery(o)[_adjacent_query[r]](s) : o.insertAdjacentHTML(_adjacent_where[r], s)
			} catch (ex) {
				html(o, frag(s), r)
			}
		} else {
			let p = r % 2 ? o : o.parentNode
			p && p.insertBefore(s, r === 0 ? o.nextSibling : r === 1 ? o.firstChild : r === 2 ? o : null)
	}
	}
}
const append  = function(o, s) {html(o, s, 3); return o.lastElementChild || o.lastChild}
const prepend = function(o, s) {html(o, s, 1); return o.firstElementChild || o.firstChild}
const before  = function(o, s) {html(o, s, 2); return o.previousElementSibling || o.previousSibling}
const after   = function(o, s) {html(o, s, 0); return o.nextElementSibling || o.nextSibling}
const replaceWith = function(o, s) {
	let a = o.nextSibling
	if (a) {
		o.parentNode.removeChild(o)
		return before(a, s)
	} else {
		let p = o.parentNode
		p.removeChild(o)
		return append(p, s)
	}
}

export {el, html, append, prepend, before, after, replaceWith}